#!/usr/bin/python
# -*- coding: utf-8 -*-

u"""
"""

__version__ = '$Id$'


import unittest

import sys
import os
# find the local copy
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))


from bipy.gamebase import GameState as OrigGameState
from bipy.gamebase import GameBase

from test_gamebase import TestGameBase
from test_gamebase import TestState
from test_gamebase import EventTestState


#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
class PygameEventTestState(EventTestState):

    def __init__(self, *args, **kwargs):
        super(PygameEventTestState, self).__init__(*args, **kwargs)

    def post_events(self):
        #    Default handlers:
        #        self.on_close listens to the event_quit event
        #        self.init listens to event_init, init state specific things
        #        self.exit listens to event_exit, clean up state specific things
        #    Internal use for the state scheduler:
        #        self._on_activate_scheduler listens to event_activate_state
        #        self._on_deactivate_scheduler listens to event_deactivate_state


        #    QUIT	     none
        #    ACTIVEEVENT	     gain, state
        #    KEYDOWN	     unicode, key, mod
        #    KEYUP	     key, mod
        #    MOUSEMOTION	     pos, rel, buttons
        #    MOUSEBUTTONUP    pos, button
        #    MOUSEBUTTONDOWN  pos, button

        #    JOYAXISMOTION    joy, axis, value
        #    JOYBALLMOTION    joy, ball, rel
        #    JOYHATMOTION     joy, hat, value

        #    JOYBUTTONUP      joy, button
        #    JOYBUTTONDOWN    joy, button

        #    VIDEORESIZE      size, w, h
        #    VIDEOEXPOSE      none
        #    USEREVENT        code

        # post all test events
        #pygame.event.post(pygame.event.Event(type, dict))
        pygame.event.post(pygame.event.Event(pygame.QUIT, {}))
        
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':0, 'state':0x1}))
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':1, 'state':0x1}))
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':0, 'state':0x2}))
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':1, 'state':0x2}))
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':0, 'state':0x4}))
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':1, 'state':0x4}))
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':0, 'state':0x6}))
        pygame.event.post(pygame.event.Event(pygame.ACTIVEEVENT, {'gain':1, 'state':0x6}))
        
        pygame.event.post(pygame.event.Event(pygame.KEYDOWN, {'key':97, 'mod':768, 'unicode':'a'}))
        pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key':98, 'mod':768}))

        pygame.event.post(pygame.event.Event(pygame.MOUSEMOTION, {'pos':(22, 22), 'rel':(2, 2), 'buttons':(0, 0, 0)}))
        # drag
        pygame.event.post(pygame.event.Event(pygame.MOUSEMOTION, {'pos':(33, 33), 'rel':(3, 3), 'buttons':(1, 0, 0)}))
        pygame.event.post(pygame.event.Event(pygame.MOUSEMOTION, {'pos':(33, 33), 'rel':(3, 3), 'buttons':(0, 1, 0)}))
        pygame.event.post(pygame.event.Event(pygame.MOUSEMOTION, {'pos':(33, 33), 'rel':(3, 3), 'buttons':(0, 0, 1)}))
    
        pygame.event.post(pygame.event.Event(pygame.MOUSEBUTTONUP , {'pos':(44, 44), 'button':2}))
        pygame.event.post(pygame.event.Event(pygame.MOUSEBUTTONDOWN , {'pos':(55, 55), 'button':3}))

        pygame.event.post(pygame.event.Event(pygame.JOYAXISMOTION , {'joy':1, 'axis':2, 'value': 77}))
        pygame.event.post(pygame.event.Event(pygame.JOYBALLMOTION , {'joy':2, 'ball':2, 'rel': (2, 2)}))
        pygame.event.post(pygame.event.Event(pygame.JOYHATMOTION , {'joy':1, 'hat':2, 'value': 77}))
        
        pygame.event.post(pygame.event.Event(pygame.JOYBUTTONUP , {'joy':1, 'button':2}))
        pygame.event.post(pygame.event.Event(pygame.JOYBUTTONDOWN , {'joy':2, 'button':3}))
                    
        pygame.event.post(pygame.event.Event(pygame.VIDEORESIZE , {'size':(800, 600), 'w':800, 'h':600}))
        #pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE , {}))
        pygame.event.post(pygame.event.Event(pygame.USEREVENT+3 , code=333))


    def test_pygame_events(self, test_case):
        #-- default pygame events --#
        test_case.failUnlessEqual(self.EventLogger.log['event_active_event'], [((1,0), {}), 
                                                                               ((1,0), {}), 
                                                                               ((1,1), {}), 
                                                                               ((2,0), {}), 
                                                                               ((2,1), {}), 
                                                                               ((4,0), {}), 
                                                                               ((4,1), {}), 
                                                                               ((6,0), {}), 
                                                                               ((6,1), {})]) #       pygame.ACTIVEEVENT,    #  gain, state

        test_case.failUnlessEqual(self.EventLogger.log['event_joy_axis_motion'], [((1, 2, 77), {})]) #    pygame.JOYAXISMOTION,  #  joy, axis, value
        test_case.failUnlessEqual(self.EventLogger.log['event_joy_ball_motion'], [((2, 2, (2,2)), {})]) #    pygame.JOYBALLMOTION,  #  joy, ball, rel
        test_case.failUnlessEqual(self.EventLogger.log['event_joy_hat_motion'], [((1, 2, 77), {})]) #     pygame.JOYHATMOTION,   #  joy, hat, value
        test_case.failUnlessEqual(self.EventLogger.log['event_joy_button_up'], [((1, 2), {})]) #      pygame.JOYBUTTONUP,    #  joy, button
        test_case.failUnlessEqual(self.EventLogger.log['event_joy_button_down'], [((2, 3), {})]) #    pygame.JOYBUTTONDOWN,  #  joy, button
        test_case.failUnlessEqual(self.EventLogger.log['event_unknown'][0][0][0].type, pygame.event.Event(pygame.USEREVENT+3 , code=333).type)
        test_case.failUnlessEqual(self.EventLogger.log['event_unknown'][0][0][0].code, pygame.event.Event(pygame.USEREVENT+3 , code=333).code)

# TODO: test scheduling


#-------------------------------------------------------------------------------


#-------------------------------------------------------------------------------
## pygame ##
try:
    import os
    import pygame
    from bipy.pygameutils import pygamebase
    from test_gamebase import TestGameBase

    class PygameBaseStateEventTest(PygameEventTestState, pygamebase.PygameState):
        def __init__(self, *args, **kwargs):
            super(PygameBaseStateEventTest, self).__init__(*args, **kwargs)

    class TestPygameGameBase(TestGameBase):

        def setUp(self):
            self.game = pygamebase.PygameGameBase(PygameBaseStateEventTest())#TestState())
            self.state = self.game.get_game_state()
        
        def tearDown(self):
            #self.state.EventLogger.print_data()
            #self.state.EventLogger.print_time_statistics()
            self.state.EventLogger.clear()
            pygame.quit()

        def test_00_events(self):
            #raw_input(u"\n\nplease move your mouse to a screen border to not \
#interfere with the testwindow.... press enter to continue\n\n")
            
            self.game.run()
            #self.state.EventLogger.print_time_statistics()
            self.state.len_test(self)
            #self.state.EventLogger.print_data()
            self.state.test_shared_events(self)
            self.state.test_pygame_events(self)

except ImportError:
    import warnings
    warnings.warn(UserWarning(u"Pygame not present, Pygame related not tested!"))

#-------------------------------------------------------------------------------

if __name__ == '__main__':
    unittest.main()
